{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "3bf01a75-a01b-472e-bc0c-9fe97658eb46",
   "metadata": {},
   "source": [
    "## LlamaIndex <> Langchain Integrations\n",
    "\n",
    "This demo notebook shows how you can provide integrations between LlamaIndex and Langchain. It provides the following examples:\n",
    "- Using LlamaIndex as a callable tool with a Langchain agent\n",
    "- Using LlamaIndex as a memory module; this allows you to insert arbitrary amounts of conversation history with a Langchain chatbot!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c1568569",
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "import sys\n",
    "\n",
    "logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
    "logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "bb9177a4-9cb7-4211-b463-121d850b5917",
   "metadata": {},
   "source": [
    "#### Using LlamaIndex as a Callable Tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "12af1b0e-983f-4fc1-b5b4-2edeb2e8f07e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents import Tool\n",
    "from langchain.chains.conversation.memory import ConversationBufferMemory\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.agents import initialize_agent\n",
    "\n",
    "from llama_index import VectorStoreIndex, SimpleDirectoryReader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1226132b-2c5f-4073-bfdb-0e36c681c12f",
   "metadata": {},
   "outputs": [],
   "source": [
    "documents = SimpleDirectoryReader(\"../paul_graham_essay/data\").load_data()\n",
    "index = VectorStoreIndex.from_documents(documents=documents)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c9b3567-c95c-473d-afc0-516b5f35e197",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [\n",
    "    Tool(\n",
    "        name=\"LlamaIndex\",\n",
    "        func=lambda q: str(index.as_query_engine().query(q)),\n",
    "        description=\"useful for when you want to answer questions about the author. The input to this tool should be a complete english sentence.\",\n",
    "        return_direct=True,\n",
    "    ),\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "374e9f69-1f75-4a62-afdc-22f748d4bddd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# set Logging to DEBUG for more detailed outputs\n",
    "memory = ConversationBufferMemory(memory_key=\"chat_history\")\n",
    "llm = ChatOpenAI(temperature=0)\n",
    "agent_executor = initialize_agent(\n",
    "    tools, llm, agent=\"conversational-react-description\", memory=memory\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "579fbc9f-9f13-416c-bde4-7e56fb899727",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Thought: Do I need to use a tool? No\n",
      "AI: Hi Bob, nice to meet you! How can I help you today?\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Hi Bob, nice to meet you! How can I help you today?'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.run(input=\"hi, i am bob\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a9841c8e-f90b-4e40-a2f9-ad1e98bb9eef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Thought: Do I need to use a tool? Yes\n",
      "Action: GPT Index\n",
      "Action Input: What did the author do growing up?\u001b[0m> [query] Total LLM token usage: 3841 tokens\n",
      "> [query] Total embedding token usage: 8 tokens\n",
      "\n",
      "Observation: \u001b[36;1m\u001b[1;3m\n",
      "\n",
      "The author grew up writing short stories, programming on an IBM 1401, and building a computer kit with a friend. He also wrote simple games, a program to predict how high his model rockets would fly, and a word processor. He studied philosophy in college, but switched to AI and taught himself Lisp. He wrote a book about Lisp hacking and reverse-engineered SHRDLU. He also took art classes at Harvard and applied to art schools, but was disappointed by the lack of teaching and learning in the painting department at the Accademia. He also had experience with 19th century studio painting conventions, such as having a little stove fed with kindling and a nude model sitting as close to it as possible.\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n\\nThe author grew up writing short stories, programming on an IBM 1401, and building a computer kit with a friend. He also wrote simple games, a program to predict how high his model rockets would fly, and a word processor. He studied philosophy in college, but switched to AI and taught himself Lisp. He wrote a book about Lisp hacking and reverse-engineered SHRDLU. He also took art classes at Harvard and applied to art schools, but was disappointed by the lack of teaching and learning in the painting department at the Accademia. He also had experience with 19th century studio painting conventions, such as having a little stove fed with kindling and a nude model sitting as close to it as possible.'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.run(input=\"What did the author do growing up?\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "7c02eb88-5a4a-4694-9b77-cd46adc691f5",
   "metadata": {},
   "source": [
    "#### Using LlamaIndex as a memory module"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "e06a04c1-c5fa-482c-b4d7-9b3fa0f904af",
   "metadata": {},
   "outputs": [],
   "source": [
    "# try using SummaryIndex!\n",
    "from langchain import OpenAI\n",
    "from langchain.llms import OpenAIChat\n",
    "from langchain.agents import initialize_agent\n",
    "\n",
    "from llama_index import SummaryIndex\n",
    "from llama_index.langchain_helpers.memory_wrapper import GPTIndexChatMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "00e6694b-25fc-4fbc-8223-9a5605dc641f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "> [build_index_from_documents] Total LLM token usage: 0 tokens\n",
      "> [build_index_from_documents] Total embedding token usage: 0 tokens\n"
     ]
    }
   ],
   "source": [
    "index = SummaryIndex([])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "25c0b10c-bca4-49f1-9353-646a182050cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "# set Logging to DEBUG for more detailed outputs\n",
    "# NOTE: you can also use a conversational chain\n",
    "\n",
    "memory = GPTIndexChatMemory(\n",
    "    index=index,\n",
    "    memory_key=\"chat_history\",\n",
    "    query_kwargs={\"response_mode\": \"compact\"},\n",
    "    # return_source returns source nodes instead of querying index\n",
    "    return_source=True,\n",
    "    # return_messages returns context in message format\n",
    "    return_messages=True,\n",
    ")\n",
    "llm = OpenAIChat(temperature=0)\n",
    "# llm=OpenAI(temperature=0)\n",
    "agent_executor = initialize_agent(\n",
    "    [], llm, agent=\"conversational-react-description\", memory=memory\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "76193275-c47c-426c-b7e4-c54d31fda92d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "> [query] Total LLM token usage: 0 tokens\n",
      "> [query] Total embedding token usage: 0 tokens\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Thought: Do I need to use a tool? No\n",
      "AI: Hi Bob, nice to meet you! How can I help you today?\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "> Adding chunk: Human: hi, i am bob\n",
      "AI: Hi Bob, nice to meet yo...\n",
      "> [insert] Total LLM token usage: 0 tokens\n",
      "> [insert] Total embedding token usage: 0 tokens\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Hi Bob, nice to meet you! How can I help you today?'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.run(input=\"hi, i am bob\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d426239a-a38b-4ae9-838b-b6fab43970e0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "> [query] Total LLM token usage: 64 tokens\n",
      "> [query] Total embedding token usage: 0 tokens\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Thought: Do I need to use a tool? No\n",
      "AI: Your name is Bob.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "> Adding chunk: Human: what's my name?\n",
      "AI: Your name is Bob....\n",
      "> [insert] Total LLM token usage: 0 tokens\n",
      "> [insert] Total embedding token usage: 0 tokens\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Your name is Bob.'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# NOTE: the query now calls the SummaryIndex memory module.\n",
    "agent_executor.run(input=\"what's my name?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ddb06074-917e-4c54-acc6-d74ffae23766",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
